package org.mapdroid.search;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;

import org.mapdroid.R;
import org.mapdroid.data.adt.MdService;
import org.mapdroid.maps.gmaps.overlay.MdMarkerItemizedOverlay;
import org.mapdroid.utils.GeoPointConversion;

import com.google.android.maps.GeoPoint;

import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.text.Editable;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class ServiceAddressView extends Activity implements OnKeyListener, OnClickListener, OnItemClickListener{
	public static final String SERVICE = "SERVICE";

	private EditText searchAddress;
	private ListView results;
	private Button searchButton, cancelButton;
	private List<MdService> serviceList;
	private List<MdService> responseList;
	
	public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.service_address_view);
        
        searchAddress = (EditText) findViewById(R.id.search_service_address);	
        results = (ListView) findViewById(R.id.search_address_result);
        searchButton = (Button) findViewById(R.id.search_b);
        cancelButton = (Button) findViewById(R.id.cancel_b);
        results.setOnItemClickListener(this);
        searchAddress.setOnKeyListener(this);
        searchButton.setOnClickListener(this);
        cancelButton.setOnClickListener(this);
       
        serviceList = super.getIntent().getParcelableArrayListExtra(MdMarkerItemizedOverlay.LIST);
        responseList = new LinkedList<MdService>();
        
        if(serviceList==null){
        	Toast.makeText(this, R.string.no_services_notify, Toast.LENGTH_SHORT).show();
        	finish();
        }
    }
    
    @Override
    public void onDestroy() {
    	super.onDestroy();
    }
    
    @Override
    public void onPause(){
    	super.onPause();
    }

    @Override
    public void onResume(){
    	super.onResume();
    }
    
    public static ArrayList<MdService> getServiceByPosition(ArrayList<MdService> serviceList, GeoPoint pos, double rangeMeters){
    	if(rangeMeters == 0)
    		return serviceList;
    	if(serviceList == null || pos == null)
    		return null;
    	
    	double[] utmPointEnd 	= new double[2];
    	Bundle b = GeoPointConversion.geoPointToUTM(pos);
    	utmPointEnd = b.getDoubleArray(GeoPointConversion.UTM_VALUE);
    	String utmZone = b.getString(GeoPointConversion.UTM_ZONE);
    	
    	utmPointEnd[0] = utmPointEnd[0]+rangeMeters;
    	utmPointEnd[1] = utmPointEnd[1]+rangeMeters;
    	
    	GeoPoint endPoint = GeoPointConversion.utmToGeoPoint(utmPointEnd[0], utmPointEnd[1], utmZone);
    	
    	int latStartE6 = pos.getLatitudeE6();
    	int lonStartE6 = pos.getLongitudeE6();
    	int latEndE6 = endPoint.getLatitudeE6();
    	int lonEndE6 = endPoint.getLongitudeE6();
    	
    	double rangeE6 = Math.sqrt(Math.pow(latEndE6 - latStartE6, 2) + Math.pow(lonEndE6 - lonStartE6, 2));
    	
    	ArrayList<MdService> tmpList = new ArrayList<MdService>();
    	int size = serviceList.size();
    	for(int i=0; i<size; i++){
    		GeoPoint temp = serviceList.get(i).getPosition();
    		int tmpLatE6 = temp.getLatitudeE6();
    		int tmpLonE6 = temp.getLongitudeE6();
    		
    		if(	tmpLatE6 < latStartE6 + rangeE6 &&
    			tmpLatE6 > latStartE6 - rangeE6 &&
    			tmpLonE6 < lonStartE6 + rangeE6 &&
    			tmpLonE6 > lonStartE6 - rangeE6){
    			
    			tmpList.add(serviceList.get(i));
    		}
    			
    	}
    	if(tmpList.size()==0)
    		return null;
    	
    	return tmpList;
    }
    
    public static double fromMetersToWGS84(double meters) {
		// TODO Auto-generated method stub
		if(meters == 0)
			return 0;
		
    	Location a = new Location(LocationManager.GPS_PROVIDER);
    	a.setLatitude(0);
    	a.setLongitude(0);
		Location b = new Location(LocationManager.GPS_PROVIDER);
    	b.setLatitude(0);
    	b.setLongitude(0);
		
		float distanceMeter = 0;
		do{
			b.setLongitude(b.getLongitude()+0.001);
			distanceMeter = a.distanceTo(b);
		}while(distanceMeter<meters);
		
		return b.getLongitude();
	}

    public List<MdService> search(String indirizzo){
    	try{
    		List<MdService> returnList = new LinkedList<MdService>();
    		ListIterator<MdService> i = serviceList.listIterator();
    		responseList = new LinkedList<MdService>();
    		while(i.hasNext()) {
    			MdService tmpService = i.next();
    			String tmpString = tmpService.getAddress().toUpperCase(Locale.getDefault());
    			indirizzo = indirizzo.toUpperCase(Locale.getDefault());
    				
    			if(tmpString.contains(indirizzo)){
    				returnList.add(tmpService);
    				responseList.add(tmpService);
    			}
    		}
    		
    		if(returnList.size()==0)
    			return null;
    		
    		return returnList;
    		
    	}catch(IllegalArgumentException e){
			return null;
		}catch(ClassCastException E){
			return null;
    	}
    }

    public List<String> createNameList(List<MdService> lista){
    	try{
    		List<String> returnList = new LinkedList<String>();
    		ListIterator<MdService> i = lista.listIterator();
	    	while(i.hasNext()) {
				MdService f = (MdService)i.next();
				returnList.add(f.getName());
			}

	    	if(returnList.size()==0)
	    		return null;

	    	return returnList;
    	}catch(ClassCastException E){
    		return null;
    	}
    }
        
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event){
    	Editable address = searchAddress.getText();
		switch(keyCode){
			case KeyEvent.KEYCODE_DPAD_CENTER:
				
			case KeyEvent.KEYCODE_ENTER:
				List<MdService> list = search(address.toString());
				if(list!=null){
	    			List<String> strings = createNameList(list);
					results.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strings));
				}
				else{
					Toast.makeText(this, R.string.no_service_results_notify, Toast.LENGTH_LONG).show();
				}
				break;
		}
		
    	return false;
    	
    }

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		int action = arg0.getId();
		switch(action){
			case R.id.search_b:
				Editable address = searchAddress.getText();
				List<MdService> list = search(address.toString());
				if(list!=null){
					List<String> strings = createNameList(list);
					results.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strings));
				}
				else{
					Toast.makeText(this, R.string.no_service_results_notify, Toast.LENGTH_LONG).show();
				}
				break;
			case R.id.cancel_b:
				setResult(RESULT_CANCELED);
				finish();
		}
		
	}
	
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) {
		// TODO Auto-generated method stub
		try{
			MdService clickedService = responseList.get(index);
			boolean isParking = clickedService.getCategory()==0 ? true : false;
			
			Intent result = new Intent();
			result.putExtra(MdMarkerItemizedOverlay.OBJECT, clickedService);
			result.putExtra(MdMarkerItemizedOverlay.OVERLAY_DATA, isParking);
			setResult(RESULT_OK, result); 
			finish();
		}
		catch(IndexOutOfBoundsException e){
			e.printStackTrace();
		}
	}
}
